package cn.com.easy.pay.alipay.www;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import cn.com.easy.pay.alipay.www.config.AlipayConfig;
import cn.com.easy.pay.alipay.www.util.AlipaySubmit;

import com.google.common.collect.Lists;

/**
 * 支付宝工具类
 * 
 * @author nibili 2017年3月31日
 * 
 */
public class AlipayUtils {

	/**
	 * 自动跳转到有密退款页面
	 * 
	 * @param alipayConfig
	 * @param alipayParam
	 * @return
	 * @author nibili 2017年3月31日
	 * @throws IOException
	 */
	public static void requestRefundByPwdForm(HttpServletResponse httpResponse, AlipayConfig alipayConfig, AlipayRefundParam alipayRefundParam) throws IOException {
		// 有密退款
		alipayConfig.setService(AlipayConfig.SERVICE_REFUND_BY_PWD);
		// //////////////////////////////////请求参数//////////////////////////////////////

		// 把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("service", alipayConfig.getService());
		sParaTemp.put("partner", alipayConfig.getPartner());
		sParaTemp.put("_input_charset", alipayConfig.getInput_charset());
		sParaTemp.put("notify_url", alipayConfig.getNotify_url());
		sParaTemp.put("seller_user_id", alipayConfig.getSeller_id());
		sParaTemp.put("refund_date", alipayConfig.getRefund_date());
		sParaTemp.put("batch_no", alipayRefundParam.getBatch_no());
		sParaTemp.put("batch_num", alipayRefundParam.getBatch_num());
		sParaTemp.put("detail_data", alipayRefundParam.getDetail_data());

		// 建立请求
		String sHtmlText = AlipaySubmit.buildRequest(sParaTemp, "get", "确认", alipayConfig);
		httpResponse.setContentType("text/html;charset=" + alipayConfig.getInput_charset());
		httpResponse.getWriter().write(sHtmlText);// 直接将完整的表单html输出到页面
		httpResponse.getWriter().flush();
		httpResponse.getWriter().close();
	}

	/**
	 * 自动跳转到支付页面
	 * 
	 * @param alipayConfig
	 * @param alipayParam
	 * @return
	 * @author nibili 2017年3月31日
	 * @throws IOException
	 */
	public static void requestForm(HttpServletResponse httpResponse, AlipayConfig alipayConfig, AlipayPayParam alipayParam) throws IOException {
		// 把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("service", alipayConfig.getService());
		sParaTemp.put("partner", alipayConfig.getPartner());
		sParaTemp.put("seller_id", alipayConfig.getSeller_id());
		sParaTemp.put("_input_charset", alipayConfig.input_charset);
		sParaTemp.put("payment_type", alipayConfig.payment_type);
		sParaTemp.put("notify_url", alipayConfig.notify_url);
		sParaTemp.put("return_url", alipayConfig.return_url);
		sParaTemp.put("anti_phishing_key", alipayConfig.anti_phishing_key);
		sParaTemp.put("exter_invoke_ip", alipayConfig.exter_invoke_ip);
		sParaTemp.put("out_trade_no", alipayParam.getOut_trade_no());
		sParaTemp.put("subject", alipayParam.getSubject());
		sParaTemp.put("total_fee", alipayParam.getTotal_fee());
		sParaTemp.put("body", alipayParam.getBody());
		// 其他业务参数根据在线开发文档，添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.O9yorI&treeId=62&articleId=103740&docType=1
		// 如sParaTemp.put("参数名","参数值");
		// 建立请求
		String sHtmlText = AlipaySubmit.buildRequest(sParaTemp, "get", "确认", alipayConfig);
		httpResponse.setContentType("text/html;charset=" + alipayConfig.getInput_charset());
		httpResponse.getWriter().write(sHtmlText);// 直接将完整的表单html输出到页面
		httpResponse.getWriter().flush();
		httpResponse.getWriter().close();
	}

	/**
	 * 单笔数据
	 * 
	 * @author nibili 2017年4月1日
	 * 
	 */
	public static class AlipayRefundDetailDataParam {
		/** 支付宝交易号 */
		private String trade_no;
		/** 退款总金额 */
		private String total_fee;
		/** 退款理由 */
		private String body;

		/**
		 * get 支付宝交易号
		 * 
		 * @return
		 * @author nibili 2017年4月1日
		 */
		public String getTrade_no() {
			return trade_no;
		}

		/**
		 * set 支付宝交易号
		 * 
		 * @param trade_no
		 * @author nibili 2017年4月1日
		 */
		public void setTrade_no(String trade_no) {
			this.trade_no = trade_no;
		}

		/**
		 * get 退款总金额
		 * 
		 * @return
		 * @author nibili 2017年4月1日
		 */
		public String getTotal_fee() {
			return total_fee;
		}

		/**
		 * set 退款总金额
		 * 
		 * @param total_fee
		 * @author nibili 2017年4月1日
		 */
		public void setTotal_fee(String total_fee) {
			this.total_fee = total_fee;
		}

		/**
		 * get 退款理由
		 * 
		 * @return
		 * @author nibili 2017年4月1日
		 */
		public String getBody() {
			return body;
		}

		/**
		 * set 退款理由
		 * 
		 * @param body
		 * @author nibili 2017年4月1日
		 */
		public void setBody(String body) {
			this.body = body;
		}

	}

	/**
	 * 支付宝有密退款参数<br/>
	 * 具体参数 参看：https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.
	 * KNgYXT&treeId=62&articleId=104744&docType=1
	 * 
	 * @author nibili 2017年4月1日
	 * 
	 */
	public static class AlipayRefundParam {

		/** 退款批次号 */
		private String batch_no;
		/** 总笔数 */
		private String batch_num;
		/** 单笔数据集 */
		private List<AlipayRefundDetailDataParam> detailDataList;

		/**
		 * get 单笔数据集<br/>
		 * 单笔数据集参数说明
		 * 
		 * 单笔数据集格式为：第一笔交易退款数据集#第二笔交易退款数据集#第三笔交易退款数据集…#第N笔交易退款数据集；
		 * 交易退款数据集的格式为：原付款支付宝交易号^退款总金额^退款理由； 不支持退分润功能。<br/>
		 * “退款理由”长度不能大于256字节，“退款理由”中不能有“^”、“|”、“$”、“#”等影响detail_data格式的特殊字符；
		 * 
		 * @return
		 * @author nibili 2017年4月1日
		 */
		public String getDetail_data() {
			if (CollectionUtils.isNotEmpty(detailDataList) == true) {
				List<String> detailDataStringList = Lists.newArrayList();
				for (AlipayRefundDetailDataParam alipayRefundDetailDataParam : detailDataList) {
					// “退款理由”长度不能大于256字节，“退款理由”中不能有“^”、“|”、“$”、“#”等影响detail_data格式的特殊字符；
					String body = alipayRefundDetailDataParam.getBody().replaceAll("[\\^|\\||\\$|\\#]", ";");
					String detail_data = alipayRefundDetailDataParam.getTrade_no() + "^" + alipayRefundDetailDataParam.getTotal_fee() + "^" + body;
					detailDataStringList.add(detail_data);
				}
				// 单笔数据集格式为：第一笔交易退款数据集#第二笔交易退款数据集#第三笔交易退款数据集…#第N笔交易退款数据集；
				return StringUtils.join(detailDataStringList, "#");
			} else {
				return "";
			}
		}

		/**
		 * get 退款批次号
		 * 
		 * @return
		 * @author nibili 2017年4月1日
		 */
		public String getBatch_no() {
			return batch_no;
		}

		/**
		 * set 退款批次号
		 * 
		 * @param batch_no
		 * @author nibili 2017年4月1日
		 */
		public void setBatch_no(String batch_no) {
			this.batch_no = batch_no;
		}

		/**
		 * get 总笔数
		 * 
		 * @return
		 * @author nibili 2017年4月1日
		 */
		public String getBatch_num() {
			return batch_num;
		}

		/**
		 * set 总笔数
		 * 
		 * @param batch_num
		 * @author nibili 2017年4月1日
		 */
		public void setBatch_num(String batch_num) {
			this.batch_num = batch_num;
		}

		/**
		 * get 单笔数据集
		 * 
		 * @return
		 * @author nibili 2017年4月1日
		 */
		public List<AlipayRefundDetailDataParam> getDetailDataList() {
			return detailDataList;
		}

		/**
		 * set 单笔数据集
		 * 
		 * @param detailDataList
		 * @author nibili 2017年4月1日
		 */
		public void setDetailDataList(List<AlipayRefundDetailDataParam> detailDataList) {
			this.detailDataList = detailDataList;
		}

	}

	/**
	 * 支付要动态变化的参数
	 * 
	 * @author nibili 2017年3月31日
	 * 
	 */
	public static class AlipayPayParam {

		/** 商户订单号，商户网站订单系统中唯一订单号，必填 */
		private String out_trade_no = "";

		/** 订单名称，必填 */
		private String subject = "";

		/** 付款金额，必填 */
		private String total_fee = "";

		/** 商品描述，可空 */
		private String body = "";

		/**
		 * get 商户订单号，商户网站订单系统中唯一订单号，必填
		 * 
		 * @return
		 * @author nibili 2017年3月31日
		 */
		public String getOut_trade_no() {
			return out_trade_no;
		}

		/**
		 * set 商户订单号，商户网站订单系统中唯一订单号，必填
		 * 
		 * @param out_trade_no
		 * @author nibili 2017年3月31日
		 */
		public void setOut_trade_no(String out_trade_no) {
			this.out_trade_no = out_trade_no;
		}

		/**
		 * get 订单名称，必填
		 * 
		 * @return
		 * @author nibili 2017年3月31日
		 */
		public String getSubject() {
			return subject;
		}

		/**
		 * set 订单名称，必填
		 * 
		 * @param subject
		 * @author nibili 2017年3月31日
		 */
		public void setSubject(String subject) {
			this.subject = subject;
		}

		/**
		 * get 付款金额，必填
		 * 
		 * @return
		 * @author nibili 2017年3月31日
		 */
		public String getTotal_fee() {
			return total_fee;
		}

		/**
		 * set 付款金额，必填
		 * 
		 * @param total_fee
		 * @author nibili 2017年3月31日
		 */
		public void setTotal_fee(String total_fee) {
			this.total_fee = total_fee;
		}

		/**
		 * get 商品描述，可空
		 * 
		 * @return
		 * @author nibili 2017年3月31日
		 */
		public String getBody() {
			return body;
		}

		/**
		 * set 商品描述，可空
		 * 
		 * @param body
		 * @author nibili 2017年3月31日
		 */
		public void setBody(String body) {
			this.body = body;
		}

	}

}
